package com.dotflat.check.controller;

import com.dotflat.check.domain.C.*;
import com.dotflat.check.domain.C.PO.*;
import com.dotflat.check.domain.CheckCard;
import com.dotflat.check.domain.RelId;
import com.dotflat.check.repository.CardInfoRepository;
import com.dotflat.check.repository.CheckerRepository;
import com.dotflat.check.service.CheckerService;
import com.dotflat.check.service.RelIdService;
import com.dotflat.util.AccessControlUserIdUtil;
import com.dotflat.util.excelUtil.StringUtils;
import com.matt.commons.dto.sso.StaffDTO;
import com.matt.domain.record.CheckRecord;
import com.matt.foundation.utils.CopyUtils;
import com.matt.foundation.utils.DateUtil;
import com.matt.repository.record.CheckRecordRepository;
import com.matt.service.remoteCall.SsoCallService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 巡检字典Controller
 *
 * @author #
 * @date 2021-11-25
 */
@RestController
@RequestMapping("/WebServices")
@Slf4j
@Api(tags = "C# - 接口")
public class CCheckerController {

    @Autowired
    private CheckRecordRepository checkRecordRepository;

    @Autowired
    private CardInfoRepository cardInfoRepository;

    @Autowired
    private CheckerRepository checkerRepository;

    @Autowired
    private RelIdService relIdService;

    @Autowired
    private SsoCallService ssoCallService;

    @Autowired
    private CheckerService checkerService;


    @ApiOperation(value = "考勤 - 用户信息")
    @PostMapping(value = "/")
    public void getParamXml(@RequestBody String paramXml, HttpServletRequest request, HttpServletResponse response) {
        String result = "";
        if (paramXml.indexOf("GetAttendanceUser") >= 0) {
            result = getAttendanceUser(paramXml);
        }
        if (paramXml.indexOf("GetClassListInfo") >= 0) {
            result = getClassListInfoResult(paramXml);
        }
        if (paramXml.indexOf("GetGuardianListInfo2") >= 0) {
            result = GetGuardianListInfo2Result(paramXml);
        }
        if (paramXml.indexOf("GetGuardianChild") >= 0) {
            result = GetGuardianChildResult(paramXml);
        }
        if (paramXml.indexOf("GetAttendanceCard") >= 0) {
            result = GetAttendanceCardResult(paramXml);
        }
        System.out.println(result);
        try {
            response.setHeader("Content-type", "text/xml");
            response.getWriter().print(result);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    @ApiOperation(value = "考勤 - 用户信息")
    public String getAttendanceUser(@RequestBody String paramXml) {
        List<GetAttendanceUserResult> userResultList = new ArrayList<>();
        try {
            AttendanceUser attendanceUser = AttendanceUser.dom4jXml(paramXml);

            Integer kgId = attendanceUser.getKgId();
            RelId relId = relIdService.findById(kgId);
            //获取园区ID
            String areaId = relId.getUserId();

            //有卡教师返回
            List<CheckCard> checkCardList = checkerService.findByTypeAndAreaId(2, areaId);
            //返回大于0，否则没必要跑代码
            List<StaffDTO> staffDTOList = ssoCallService.getStaffDTOList(areaId);
            staffDTOList.stream().forEach(o -> {
                GetAttendanceUserResult getAttendanceUserResult = new GetAttendanceUserResult();
                getAttendanceUserResult.setUserName(o.getRealName());
                getAttendanceUserResult.setUserId(o.getId());
                getAttendanceUserResult.setUserType(2);
                getAttendanceUserResult.setSex(o.getGender());
                checkCardList.stream().forEach(q -> {
                    if (StringUtils.equals(o.getId(), q.getUserId())) {
                        getAttendanceUserResult.setSACardNo(q.getCardCode());
                    }
                    userResultList.add(getAttendanceUserResult);
                });
            });
            //学生返回
            List<CheckCard> childrenCardList = checkerService.findByTypeAndAreaId(1, areaId);
            List<GetAttendanceUserResult> resultList = cardInfoRepository.getKgIdInfo(areaId, attendanceUser.getModifyTime());
            resultList.stream().forEach(o -> {
                o.setUserType(1);
                childrenCardList.stream().forEach(q -> {
                    if (StringUtils.equals(o.getUserId(), q.getUserId())) {
                        o.setSACardNo(q.getCardCode());
                    }
                });
            });
            userResultList.addAll(resultList);

            //家长返回
            //有卡家长
            List<CheckCard> userCardList = checkerService.findByTypeAndAreaId(3, areaId);
            List<GetAttendanceUserResult> userList = cardInfoRepository.getKgIdByUsers(areaId);
            userList.stream().forEach(o -> {
                o.setUserType(3);
                userCardList.stream().forEach(q -> {
                    if (StringUtils.equals(o.getUserId(), q.getUserId())) {
                        o.setSACardNo(q.getCardCode());
                    }
                });
            });
            userResultList.addAll(userList);

            List<String> ids = userResultList.stream().map(k -> k.getUserId()).collect(Collectors.toList());
            List<String> classInfoID = userResultList.stream().filter(s -> !StringUtils.equals(s.getClassInfoID(),"0")).map(k -> k.getClassInfoID()).collect(Collectors.toList());
            ids.addAll(classInfoID);
            List<RelId> relIdList = relIdService.findByUserIdIn(ids);
            List<GetAttendanceUser> ret = userResultList.stream().map(o -> {
                GetAttendanceUser po = new GetAttendanceUser();
                CopyUtils.copyProperties(o, po);
                po.setUserId(getRelId(relIdList, o.getUserId()));
                po.setClassInfoID(getRelId(relIdList, o.getClassInfoID()));
                po.setKgId(kgId);
                return po;
            }).collect(Collectors.toList());
            return GetAttendanceUser.convertToXML(ret);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    Integer getRelId(List<RelId> relIdList, String id) {
        if (StringUtils.equals(id,"")){
            return 0;
        }
        for (int i = 0; i < relIdList.size(); i++) {
            if (StringUtils.equals(relIdList.get(i).getUserId(), id)) {
                return relIdList.get(i).getId();
            }
        }
        return 0;
    }
    Integer getRelationship(String relationshipName) {
        if (StringUtils.equals(relationshipName,"父亲") || StringUtils.equals(relationshipName,"爸爸") ){
            return 1;
        }
        if (StringUtils.equals(relationshipName,"母亲") || StringUtils.equals(relationshipName,"妈妈") ){
            return 2;
        }
        if (StringUtils.equals(relationshipName,"爷爷") ){
            return 3;
        }
        if (StringUtils.equals(relationshipName,"奶奶") ){
            return 4;
        }
        if (StringUtils.equals(relationshipName,"姥姥") ){
            return 5;
        }
        if (StringUtils.equals(relationshipName,"姥爷") ){
            return 6;
        }
        if (StringUtils.equals(relationshipName,"其他") ){
            return 7;
        }
        return 0;
    }
    @ApiOperation(value = "考勤 - 班级信息")
    public String getClassListInfoResult(@RequestBody String paramXml) {
        GetClassListInfo attendanceUser = null;
        try {
            attendanceUser = GetClassListInfo.dom4jXml(paramXml);
        } catch (Exception e) {
            e.printStackTrace();
        }
        Integer kgId = attendanceUser.getKgId();
        RelId relId = relIdService.findById(kgId);
        //获取园区ID
        String areaId = relId.getUserId();
        //获取园区名称
        Map map = ssoCallService.getStaffNameAndAreaName(null, areaId);
        //学生返回
        List<GetClassListInfoResult> resultList = cardInfoRepository.getKgIdByClassListInfo(areaId);
        List<String> ids = resultList.stream().map(k -> k.getClassInfoID()).collect(Collectors.toList());
        List<RelId> relIdList = relIdService.findByUserIdIn(ids);
        List<GetClassListInfoResultPO> ret = resultList.stream().map(o -> {
            GetClassListInfoResultPO po = new GetClassListInfoResultPO();
            CopyUtils.copyProperties(o, po);
            po.setClassInfoID(getRelId(relIdList, o.getClassInfoID()));
            po.setCreator(map.get("areaName").toString());
            po.setKgId(kgId);
            return po;
        }).collect(Collectors.toList());

        return GetClassListInfoResultPO.convertToXML(ret);
    }

    @ApiOperation(value = "考勤 - 家长信息")
    public String GetGuardianListInfo2Result(@RequestBody String paramXml) {
        GetGuardianListInfo2 getGuardianListInfo2 = null;
        try {
            getGuardianListInfo2 = GetGuardianListInfo2.dom4jXml(paramXml);
        } catch (Exception e) {
            e.printStackTrace();
        }
        Integer kgId = getGuardianListInfo2.getKgId();
        RelId relId = relIdService.findById(kgId);
        //获取园区ID
        String areaId = relId.getUserId();
        //获取园区名称
        Map map = ssoCallService.getStaffNameAndAreaName(null, areaId);

        //家长信息
        List<GetGuardianListInfo2Result> resultList = cardInfoRepository.getKgIdByGuardianListInfo(areaId, getGuardianListInfo2.getModifyTime());
        //String转int id
        List<String> childId = resultList.stream().map(k -> k.getChildId()).collect(Collectors.toList());
        List<String> userId = resultList.stream().map(k -> k.getUserId()).collect(Collectors.toList());
        childId.addAll(userId);
        List<RelId> relIdList = relIdService.findByUserIdIn(childId);

        List<GetGuardianListInfo2ResultPO> listInfo2ResultPOS = resultList.stream().map(o -> {
            GetGuardianListInfo2ResultPO po = new GetGuardianListInfo2ResultPO();
            CopyUtils.copyProperties(o, po);
            po.setBirth(DateUtil.formatDateToStr(o.getBirth()));
            po.setChildId(getRelId(relIdList, o.getChildId()));
            Integer userIdPO = getRelId(relIdList, o.getUserId());
            po.setUserId(userIdPO);
            po.setMainUserId(userIdPO);
            po.setGuardianInfoId(userIdPO);
            po.setModifyTime("2020-06-06 00:00:00");
            po.setModifier(map.get("areaName").toString());
            po.setRelationship(getRelationship(o.getRelationshipName()));
            po.setKgId(kgId);
            return po;
        }).collect(Collectors.toList());
        return GetGuardianListInfo2ResultPO.convertToXML(listInfo2ResultPOS);
    }

    @ApiOperation(value = "考勤 - 家长关系")
    public String GetGuardianChildResult(@RequestBody String paramXml) {
        GetGuardianChild getGuardianChild = null;
        try {
            getGuardianChild = GetGuardianChild.dom4jXml(paramXml);
        } catch (Exception e) {
            e.printStackTrace();
        }
        Integer kgId = getGuardianChild.getKgId();
        RelId relId = relIdService.findById(kgId);
        //获取园区ID
        String areaId = relId.getUserId();
        //学生返回
        List<GetGuardianListInfo2Result> resultList = cardInfoRepository.getKgIdByGuardianListInfo(areaId, getGuardianChild.getModifyTime());
        List<String> childId = resultList.stream().map(k -> k.getChildId()).collect(Collectors.toList());

        List<String> userId = resultList.stream().map(k -> k.getUserId()).collect(Collectors.toList());
        childId.addAll(userId);
        List<RelId> relIdList = relIdService.findByUserIdIn(childId);

        List<GetGuardianChildResultPO> listInfo2ResultPOS = resultList.stream().map(o -> {
            GetGuardianChildResultPO po = new GetGuardianChildResultPO();
            CopyUtils.copyProperties(o, po);
            po.setChildId(getRelId(relIdList, o.getChildId()));
            Integer userIdPO = getRelId(relIdList, o.getUserId());
            po.setGuardianInfoId(userIdPO);
            return po;
        }).collect(Collectors.toList());
        return GetGuardianChildResultPO.convertToXML(listInfo2ResultPOS);
    }

    @ApiOperation(value = "考勤 - 绑卡信息")
    public String GetAttendanceCardResult(@RequestBody String paramXml) {
        GetAttendanceCard getAttendanceCard = null;
        try {
            getAttendanceCard = GetAttendanceCard.dom4jXml(paramXml);
        } catch (Exception e) {
            e.printStackTrace();
        }

        Integer kgId = getAttendanceCard.getKgId();
        RelId relId = relIdService.findById(kgId);
        //获取园区ID
        String areaId = relId.getUserId();
        List<GetAttendanceCardResult> resultList = cardInfoRepository.getGuardianListInfo2Result(areaId);
        List<String> userId = resultList.stream().map(k -> k.getUserId()).collect(Collectors.toList());
        List<RelId> relIdList = relIdService.findByUserIdIn(userId);
        List<GetAttendanceCardResultPO> attendanceCardResultPOList = resultList.stream().map(o -> {
            GetAttendanceCardResultPO po = new GetAttendanceCardResultPO();
            CopyUtils.copyProperties(o, po);
            Integer userIdPO = getRelId(relIdList, o.getUserId());
            po.setUserId(userIdPO);
            po.setCreateTime( DateUtil.formatDateToStr(o.getCreateTime()));
            po.setUpdateTime(DateUtil.formatDateToStr(o.getCreateTime()));
            po.setAccessControlUserId(AccessControlUserIdUtil.GetCardId(o.getCardNo()));
            return po;
        }).collect(Collectors.toList());
        return GetAttendanceCardResultPO.convertToXML(attendanceCardResultPOList);
    }


    @ApiOperation(value = "考勤 - 导入考勤")
    @PostMapping(value = "/UploadAttendance")
    public void UploadAttendance(@RequestBody String paramXml, HttpServletRequest request, HttpServletResponse
            response) {
        String result = "";
        if (paramXml.indexOf("UploadAttendance") >= 0) {
            result = addCheckRecord(paramXml);
        }
        try {
            response.setHeader("Content-type", "text/xml");
            response.getWriter().print(result);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    @ApiOperation(value = "考勤 - 添加考勤")
    public String addCheckRecord(@RequestBody String paramXml) {
        List<AttendanceRecord> attendanceRecordList = null;
        try {
            attendanceRecordList = AttendanceRecord.dom4jXml(paramXml);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

        //获取上传的数字userId
        List<Integer> userId = attendanceRecordList.stream().map(k -> k.getUserId()).collect(Collectors.toList());

        //关系表，查出UserId对应的用户真实StringId
        List<RelId> relIdList = relIdService.findByIdIdIn(userId);
        Map<Integer, String> int2StrCache = relIdList.stream().collect(Collectors.toMap(RelId::getId, o->o.getUserId()));

        //获取String userId
        Collection<String> userIds = int2StrCache.values();

        Date baseTime = new Date(DateUtil.startOfDayOfMilli(System.currentTimeMillis()));

        //根据ChildrenId查询当天的考勤记录
        List<CheckRecord> checkRecordList = checkRecordRepository.findByChildrenIdInAndCheckInTimeGreaterThan(userIds, baseTime);

        List<CheckRecord> recordToUpdate =
        attendanceRecordList.stream().map(o->{

            o.setUserIdV2(int2StrCache.get(o.getUserId()));

            //先处理离园记录离园

            for (int i = 0; i < checkRecordList.size() ; i++) {

                CheckRecord childrenRecord = checkRecordList.get(i);

                if (childrenRecord.getChildrenId().equals(o.getUserIdV2())){
                    //如果已经有入园记录了，并且是其他方向，不更新入园时间，直接跳过考勤机提交的记录
                    if (o.getAttendanceDirection() == 2){
                        childrenRecord.setCheckOutTime(baseTime);
                        childrenRecord.setUserType(o.getAttendanceTaget());
                        childrenRecord.setCardNo(o.getSACardNo());
                        return childrenRecord;
                    }

                    return null;
                }
            }

            //没有找到记录，则直创建新纪录
            CheckRecord checkRecord = new CheckRecord();
            checkRecord.setChildrenId(o.getUserIdV2());
            if (o.getAttendanceDirection() ==2){
                checkRecord.setCheckOutTime(baseTime);
            }else {
                checkRecord.setCheckInTime(baseTime);
            }
            checkRecord.setUserType(o.getAttendanceTaget());
            checkRecord.setCardNo(o.getSACardNo());

            return checkRecord;
        }).filter(Objects::nonNull).collect(Collectors.toList());

        if (recordToUpdate.size() > 0){
            checkRecordRepository.saveAll(recordToUpdate);
        }

        return null;
    }

}